import React, { PureComponent } from 'react';
import cx from 'classnames';
import s from './index.m.less';

export default class Input extends PureComponent {
    static defaultProps = {
        placeholder: '',
        value: '',
        className: '',
        disabled: false, // 是否禁用
        onFocus: () => {}, // 获取焦点
        onBlur: () => {}, // 失去焦点
        onClear: () => {}, // 清空数据
        onChange: v => v, // 监听值变化
        filter: () => true, // 过滤input值
        clearBtnClass: '',
        clearInput: false, // 清除内容btn
        maxLength: -1, // 字体长度
    };

    state = {
        showValue: this.props.value,
        onComposition: false,
        focus: false,
    };

    componentWillReceiveProps(nextProps) {
        if (nextProps.value != this.props.value) {
            this.setState({ showValue: nextProps.value });
        }
    }

    focus = () => {
        this.setState({ focus: true });
        setTimeout(() => {
            this.props.onFocus();
        }, 30);
    };

    blur = () => {
        setTimeout(() => {
            // 失焦后触发滚动
            $(window).scrollTop($(window).scrollTop());
            this.setState({ focus: false }, () => {
                this.props.onBlur();
            });
        }, 30);
    };

    change = e => {
        e.preventDefault();
        e.stopPropagation();

        let value = e.target.value;

        const { maxLength, onChange, filter } = this.props;

        if (!filter(value)) {
            return;
        }

        if (!maxLength || maxLength <= 0) {
            this.setState({
                showValue: value,
            });
            onChange(value);
            return;
        }
        const maxLen = Number(maxLength);

        if (value.length > maxLen) {
            if (!this.state.onComposition) {
                value = value.slice(0, maxLen);
            }
        }
        if (!this.state.onComposition) {
            this.setState({
                showValue: value,
            });
            onChange(value);
        } else {
            this.setState({
                showValue: value,
            });
        }
    };

    clear = e => {
        e.preventDefault();
        e.stopPropagation();
        this.props.onClear();
        this.setState({ showValue: '' });
    };

    handleComposition = e => {
        const { maxLength, onChange } = this.props;
        if (!maxLength || maxLength <= 0) {
            return;
        }
        const maxLen = Number(maxLength);
        if (e.type === 'compositionend') {
            onChange(this.state.showValue.slice(0, maxLen));
            this.setState(prevState => ({
                onComposition: false,
                showValue: prevState.showValue.slice(0, maxLen),
            }));
        } else {
            this.setState({ onComposition: true });
        }
    };

    render() {
        const {
            disabled,
            value,
            placeholder,
            className,
            clearBtnClass,
            inputNum,
            clearInput,
            inputRef = () => {},
            ...otherProps
        } = this.props;
        const { showValue, focus } = this.state;

        return (
            <div className={s.inputContainer}>
                <input
                    {...otherProps}
                    ref={inputRef}
                    className={cx(s.input, className)}
                    disabled={disabled}
                    value={showValue}
                    onCompositionStart={this.handleComposition}
                    onCompositionUpdate={this.handleComposition}
                    onCompositionEnd={this.handleComposition}
                    placeholder={placeholder}
                    onFocus={this.focus}
                    onChange={this.change}
                    onBlur={this.blur}
                />
                {clearInput && !!value && focus && (
                    <div className={cx(s.clearInput, clearBtnClass)} onClick={this.clear} />
                )}
            </div>
        );
    }
}
